home *** CD-ROM | disk | FTP | other *** search
- #ifndef _BYTEARRAYWRAPPER_INCLUDE
- #define _BYTEARRAYWRAPPER_INCLUDE
-
- #include <ole2.h>
- #include <olectl.h>
- #include "asyncstg.h"
- #include "bytearr.h"
-
- class CAsyncByteArrayFactory;
- class CLockBytesConnectionPoint;
- //class CFillLockBytesConnectionPoint;
- //class CBindStatusCallbackConnectionPoint;
-
- class CAsyncByteArray : public ILockBytes, public IFillLockBytes, public IConnectionPointContainer
- {
- public:
- // IUnknown methods
- HRESULT _stdcall QueryInterface(REFIID riid, void** ppObject);
- ULONG _stdcall AddRef();
- ULONG _stdcall Release();
-
- // ILockBytes methods
- HRESULT __stdcall ReadAt(ULARGE_INTEGER ulOffset,void *pv, ULONG cb, ULONG *pcbRead);
- HRESULT __stdcall WriteAt(ULARGE_INTEGER ulOffset,const void *pv, ULONG cb, ULONG *pcbWritten);
- HRESULT __stdcall Flush( void);
- HRESULT __stdcall SetSize(ULARGE_INTEGER cb);
- HRESULT __stdcall LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType);
- HRESULT __stdcall UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType);
- HRESULT __stdcall Stat(STATSTG *pstatstg, DWORD grfStatFlag);
-
- // IFillLockBytes methods
- HRESULT __stdcall SetFillSize(ULARGE_INTEGER cb);
- HRESULT __stdcall FillAppend(void const *pv, ULONG cb, ULONG *pcbWritten);
- HRESULT __stdcall FillAt(ULARGE_INTEGER ulOffset, void const *pv, ULONG cb, ULONG *pcbWritten);
- HRESULT __stdcall Terminate(DWORD dwStatus);
-
- // IConnectionPointContainer methods
- HRESULT __stdcall EnumConnectionPoints(LPENUMCONNECTIONPOINTS FAR* ppEnum);
- HRESULT __stdcall FindConnectionPoint(REFIID iid, LPCONNECTIONPOINT FAR* ppCP);
-
- friend CAsyncByteArrayFactory;
- friend CLockBytesConnectionPoint;
- private:
-
- CAsyncByteArray();
- HRESULT Initialize(IUnknown* punkOuter);
- ~CAsyncByteArray();
-
- #define FILLINFOINITSIZE (10)
- #define FILLINFOREALLOCSIZE (10)
-
- class CInnerUnk : public IUnknown
- {
- public:
- // IUnknown methods
- HRESULT _stdcall QueryInterface(REFIID riid, void** ppObject);
- ULONG _stdcall AddRef();
- ULONG _stdcall Release();
-
- CInnerUnk(CAsyncByteArray* pObj);
-
- CAsyncByteArray* m_pObj;
- } *m_punkInner;
- friend CInnerUnk;
-
- IUnknown* m_punkOuter;
- ULONG m_dwRefCount;
-
- CRITICAL_SECTION m_sectLBConnect; // protects m_pCacheArray/m_pDataArray pointer manipulations
- ILockBytes* m_pCacheArray; // Cache Byte Array
- ILockBytes* m_pDataArray; // optional Data Byte Array
- CLockBytesConnectionPoint* m_pLBConnect;
- //CFillLockBytesConnectionPoint* pFillLBConnect;
- //CBindStatusCallbackConnectionPoint* pBSCConnect;
-
-
- // Access to FILLINFO etc is guarded with the following:
- CRITICAL_SECTION m_sectNewReadAllowed; // Indicates if new read access can be obtained, has to be release immediately
- DWORD m_nReadsPending; // number of outstanding reads
- HANDLE m_hevntNoReadsPending; // m_nReadsPending has reached 0
-
- // To obtain read access: READFILLINFOLOCK
- // To release read access: READFILLINFOUNLOCK
- // To obtain exclusive write access: WRITEFILLINFOLOCK
- // To relase exclusive write access: WRITEFILLINFOUNLOCK
-
- // Deadlock: May not use WRITEFILLINFOLOCK with a pending READFILLINFOLOCK in the same thread
-
- // FILLINFO describes a valid block of data within the Cache Byte Array
- typedef struct _tagFillInfo
- {
- DWORDLONG ulOffset;
- DWORDLONG cb;
- } FILLINFO;
- FILLINFO* m_pFillInfo; // An array of FILLINFO structs
-
- DWORD m_nFillInfo; // number of FILLINFO structs in m_pFillInfo
- DWORD m_nFillAlloc; // number of allocated FILLINFO structs
- DWORDLONG m_ulFillSize; // 0 indicates not set!
- HANDLE m_hevntNewFillInfo; // Pulsed when FillInfo should be reinterpreted
-
- BOOL m_bTerminated; // used to decide if to return STG_E_PENDING or E_FAIL
- BOOL m_bBlocking;
- };
-
- extern ULONG g_dwRefCount;
-
- // To obtain read access:
- #define READFILLINFOLOCK \
- { \
- EnterCriticalSection(&m_sectNewReadAllowed); \
- InterlockedIncrement((LPLONG) &m_nReadsPending); \
- if (!ResetEvent(m_hevntNoReadsPending)) \
- { \
- \
- } \
- LeaveCriticalSection(&m_sectNewReadAllowed); \
- }
- // To release read access:
- #define READFILLINFOUNLOCK \
- { \
- if (!InterlockedDecrement((LPLONG) &m_nReadsPending)) \
- { \
- if (!SetEvent(m_hevntNoReadsPending)) \
- { \
- \
- } \
- } \
- }
- // To obtain exclusive write access:
- #define WRITEFILLINFOLOCK \
- { \
- WaitForSingleObject(m_hevntNoReadsPending, INFINITE); \
- EnterCriticalSection(&m_sectNewReadAllowed); \
- WaitForSingleObject(m_hevntNoReadsPending, INFINITE); \
- }
-
- // To relase exclusive write access:
- #define WRITEFILLINFOUNLOCK \
- { \
- LeaveCriticalSection(&m_sectNewReadAllowed); \
- }
-
- #endif
-